import React, {FC} from 'react';
import "./index.less";
import {publicApiType, ScrollMenu, VisibilityContext} from 'react-horizontal-scrolling-menu';
import 'react-horizontal-scrolling-menu/dist/styles.css';
import classNames from "classnames";
import {LeftOutlined, RightOutlined} from "@ant-design/icons";
import {ItemType} from 'node_modules/react-horizontal-scrolling-menu/dist/types/types';
import {DragDealer} from "@/components/HxScrollMenu/DragDealer";


interface HxScrollMenuProps {
  className?: string;
  children?: ItemType | ItemType[];
  showArrow?: boolean;
  donothing?: boolean;
}

function onWheel(apiObj: publicApiType, ev: React.WheelEvent): void {
  const isThouchpad = Math.abs(ev.deltaX) !== 0 || Math.abs(ev.deltaY) < 15;
  if (isThouchpad) {
    ev.stopPropagation();
    return;
  }
  if (ev.deltaY < 0) {
    // apiObj.scrollPrev();
    apiObj.scrollToItem(apiObj.getPrevElement(), 'smooth', 'start')
  } else {
    // apiObj.scrollNext();
    apiObj.scrollToItem(apiObj.getNextElement(), 'smooth', 'end')
  }
}

function LeftArrow() {
  const visibility = React.useContext<publicApiType>(VisibilityContext);
  const disabled = visibility.useLeftArrowVisible();
  return (
    <div
      onClick={() => visibility.scrollPrev()}
      //onClick={() => visibility.scrollToItem(visibility.getPrevElement(), 'smooth', 'start')}
      className={classNames("scroll-menu-arrow-btn", "left-arrow", {"scroll-menu-arrow-btn-disabled": disabled})}
    >
      <LeftOutlined/>
    </div>
  );
}

function RightArrow() {
  const visibility = React.useContext<publicApiType>(VisibilityContext);
  const disabled = visibility.useRightArrowVisible();
  return (
    <div
      onClick={() => visibility.scrollNext()}
      //onClick={() => visibility.scrollToItem(visibility.getNextElement(), 'smooth', 'end')}
      className={classNames("scroll-menu-arrow-btn", "right-arrow", {"scroll-menu-arrow-btn-disabled": disabled})}
    >
      <RightOutlined/>
    </div>
  );
};

export const useSwipe = () => {
  const pos = React.useRef({start: {x: 0, y: 0}, end: {x: 0, y: 0}});
  const minSwipeDistance = 50;
  const onMouseDown = () => (ev: React.MouseEvent) => {
    pos.current.start = {x: ev.clientX, y: ev.clientY};
  };
  const onMouseMove = () => (ev: React.MouseEvent) => {
    pos.current.end = {x: ev.clientX, y: ev.clientY};
  };
  const onMouseUp = (apiObj: publicApiType) => () => {
    const horDiff = pos.current.end.x - pos.current.start.x;
    const toLeft = horDiff < 0 && Math.abs(horDiff) > minSwipeDistance;
    const toRight = horDiff > 0 && Math.abs(horDiff) > minSwipeDistance;

    if (toLeft) {
      apiObj.scrollNext();
    }
    if (toRight) {
      apiObj.scrollPrev();
    }
  };

  return {onMouseDown, onMouseMove, onMouseUp};
};

const HxScrollMenu: FC<HxScrollMenuProps> = (props) => {
  const {showArrow = true, className, children, donothing=false} = props;

  //const {onMouseDown, onMouseMove, onMouseUp} = useSwipe();
  const ref = React.useRef<publicApiType>({} as publicApiType); // 使用类型断言初始化

  /*React.useEffect(() => {
      //现代浏览器默认将某些事件（如 wheel 和 touchmove）的监听器标记为 passive，以提高性能。
      //passive: true 时监听器会忽略 ev.preventDefault()，因此无法阻止默认行为， 就会出现ScrollMenu滚动时，页面（如果允许）也会跟着滚动
      const handleTouchMove = (ev: TouchEvent) => {
          ev.preventDefault();
      };
      const handleWheel = (ev: WheelEvent) => {
          ev.preventDefault();
      };
      const node = ref.current?.scrollContainer.current;
      node?.addEventListener('touchmove', handleTouchMove, {passive: false});
      node?.addEventListener('wheel', handleWheel, {passive: false});
      return () => {
          node?.removeEventListener('touchmove', handleTouchMove);
          node?.removeEventListener('wheel', handleWheel);
      }
  }, [ref]);*/

  // NOTE: 使用鼠标拖拽 来控制横向滚动
  const dragState = React.useRef(new DragDealer());
  const handleDrag = (t: publicApiType) =>
    (ev: React.MouseEvent) =>
      dragState.current.dragMove(ev, (posDiff) => {
        if (t.scrollContainer.current) {
          t.scrollContainer.current.scrollLeft += posDiff;
        }
      });
  const onMouseDown = React.useCallback(
    () => dragState.current.dragStart,
    [dragState],
  );
  const onMouseUp = React.useCallback(
    () => dragState.current.dragStop,
    [dragState],
  );

  if(donothing){
    return children || []
  }

  return (
    <div className={classNames("hx-scroll-menu-container", className)}>
      <ScrollMenu
        LeftArrow={showArrow ? LeftArrow : undefined}
        RightArrow={showArrow ? RightArrow : undefined}
        //onWheel={onWheel}
        onMouseDown={onMouseDown}
        //onMouseMove={onMouseMove}
        onMouseMove={handleDrag}
        onMouseUp={onMouseUp}
        apiRef={ref}
      >
        {children || []}
      </ScrollMenu>
    </div>
  );
};

export default HxScrollMenu;
